package game.spider.peri;

import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.Log;
import net.ds0101.framework.android.neox.action.NXAction;
import net.ds0101.framework.android.neox.action.NXPlay;
import net.ds0101.framework.android.neox.action.NXRepeatForever;
import net.ds0101.framework.android.neox.main.NXDirector;
import net.ds0101.framework.android.neox.widget.NXBitmapSheet;
import net.ds0101.framework.android.neox.widget.NXSprite;

public class Monster extends NXSprite {
	private static final int MAX_SPEED = 4;
	private static final int TARGET_LESS = Integer.MIN_VALUE;
	private static final int DURATION_FACTOR = 900;
	private int mSpeedX = 0, mSpeedY = 0;
	private int mRow;
	private int mDuration;
	private static Rect mViewRC = new Rect();
	private NXAction mAction;

	public Monster(NXBitmapSheet bmps) {
		super(bmps);
		
		synchronized (mViewRC) {
			if (mViewRC.isEmpty()) {
				mViewRC.set(0, 0, NXDirector.getScreenWidth(), NXDirector.getScreenHeight());
			}
		}
		randomPosition(new Region(mViewRC));
		recalcBehavior();
	}
	
	public final void randomPosition(Region area) {
		int x = 0, y = 0;
		do {
			x = (int) (Math.random()* (mViewRC.width() - width())) + height() / 2;
			y = (int) (Math.random()* (mViewRC.height() - height())) + height() / 2;
		} while (null != area && (!area.contains(x, y)));
		position(x, y);
	}
	
	public void recalcBehavior(int speedX, int speedY) {
		// Random target.
		if (0 == speedX && 0 == speedY) {
			double xRandom = Math.random();
			double yRandom = Math.random();
			mSpeedX = (int) (xRandom * MAX_SPEED); 
			mSpeedY = (int) (yRandom * MAX_SPEED); 
			if (0 == mSpeedX && 0 == mSpeedY) {
				mSpeedX = 2;
			}
			
			if ((int)(mSpeedX) % 2 == 0) {
				mSpeedX = -mSpeedX;
			}
			if ((int)(mSpeedY) % 2 == 0) {
				mSpeedY = -mSpeedY;
			}
		} else {
			mSpeedX = speedX;
			mSpeedY = speedY;
		}
		
		if (Math.abs(mSpeedX) > Math.abs(mSpeedY)) {
			if (mSpeedX > 0) {
				mRow = 2;
			} else {
				mRow = 1;
			}
			mDuration = DURATION_FACTOR / Math.abs(mSpeedX);
		} else {
			if (mSpeedY > 0) {
				mRow = 0;
			} else {
				mRow = 3;
			}
			mDuration = DURATION_FACTOR / Math.abs(mSpeedY);
		}
		
		stopAction(mAction);
		mAction = NXRepeatForever.action(new NXPlay(mDuration, 
				new Point(0, mRow), new Point(4, mRow)));
		runAction(mAction);
	}
	
	public void recalcBehavior() {
		recalcBehavior(0, 0);
	}
	
	public void reverse() {
		recalcBehavior(-mSpeedX, -mSpeedY);
	}
	
	public void target(int x, int y) {
		if (TARGET_LESS != x && TARGET_LESS != y) {
			int speedX = 0;
			int speedY = 0;
			if (positionX() < x) {
				// TODO: adjust speed for different.
				speedX = 2;
			} else if (positionX() > x) {
				speedX = -2;
			}
			
			if (positionY() < y - 5/*vertical compensation*/) {
				speedY = 2;
			} else if (positionY() > y + 5) {
				speedY = -2;
			}
			recalcBehavior(speedX, speedY);
		}
	}
	
	public void step() {
		/*if (positionX() <= width() / 2 || (positionX() > mViewRC.width() - width() / 2)
				|| positionY() <= height() / 2 || (positionY() > mViewRC.height() - height() / 2)) {
			reverse();
		}*/ 
		synchronized (mViewRC) {
			// cross mode
			/*
			if (positionX() < 0) {
				position(mViewRC.width(), positionY());
			}
			if (positionY() < 0) {
				position(positionX(), mViewRC.height());
			}
			if (positionX() > mViewRC.width()) {
				position(0, positionY());
			}
			if (positionY() > mViewRC.height()) {
				position(positionX(), 0);
			}
			*/
			
			// reflection mode
			boolean directionChanged = false;
			if (positionX() <= 0 ||
					positionX() >= mViewRC.width()) {
				mSpeedX = -mSpeedX;
				directionChanged = true;
			}
			if (positionY() <= 0 ||
					positionY() >= mViewRC.height()) {
				mSpeedY = -mSpeedY;
				directionChanged = true;
			}
			if (directionChanged) {
				recalcBehavior(mSpeedX, mSpeedY);
			}
			position(positionX() + mSpeedX, positionY() + mSpeedY);
		}
	}
	
	public int row() {
		return mRow;
	}
	
	public int duration() {
		return mDuration;
	}
	
	synchronized public static void territory(Rect rc) {
		mViewRC.set(rc);
	}
}
